import logging
from rest_framework.response import Response
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.views import APIView
from rest_framework.renderers import JSONRenderer

from django.db.models import Q
from django.utils import timezone
from django.http import StreamingHttpResponse
import json

# 导入模型
from .models import PosterRecord, ChatSession, ChatMessage


# 导入封装好的Coze服务
from posters.CozeTool import run_coze_workflow, CozeChatBot, build_conversation_history_from_db

# 配置日志
logger = logging.getLogger(__name__)


# 海报生成接口
class PostersView(APIView):
    permission_classes = [AllowAny]
    
    def post(self, request):
        try:
            # 获取请求参数
            img = request.data.get('img')  # 图片的网络地址
            prompt = request.data.get('prompt')  # 描述
            propotion = request.data.get('propotion')  # 比例（1、2、3、4、其他）
            logo_img = request.data.get('logo_img')  # logo图片的网络地址
            logo_place = request.data.get('logo_place')  # logo的位置
            qr_img = request.data.get('qr_img')  # 二维码图片的网络地址
            qr_place = request.data.get('qr_place')  # 二维码的位置

            # 构造工作流参数
            parameters = {
                "img": img or "",
                "prompt": prompt or "",
                "propotion": propotion or "",
                "logo_img": logo_img or "",
                "logo_place": logo_place or "",
                "qr_img": qr_img or "",
                "qr_place": qr_place or ""
            }

            # 调用Coze工作流
            try:
                image_url = run_coze_workflow(parameters)
                
                # 确定海报类型
                poster_type = 'generate'  # 默认为生成
                if img:  # 如果有原图片，则为修改类型
                    if prompt:
                        poster_type = 'modify'  # 有提示词的修改
                    elif logo_img or qr_img:
                        poster_type = 'add_elements'  # 添加元素
                    else:
                        poster_type = 'enhance'  # 清晰化
                
                # 保存记录到数据库（如果用户已登录）
                if hasattr(request, 'user') and request.user.is_authenticated:
                    try:
                        PosterRecord.objects.create(
                            user=request.user,
                            image_url=image_url,
                            prompt=prompt or '',
                            poster_type=poster_type
                        )
                        logger.info(f"用户 {request.user.username} 的海报记录已保存")
                    except Exception as save_error:
                        logger.warning(f"保存海报记录失败: {str(save_error)}")

                # 返回结果
                return Response({
                    'code': 200,
                    'message': '处理成功',
                    'data': {
                        'image_url': image_url
                    }
                })
            except Exception as e:
                logger.error(f"调用Coze工作流失败: {str(e)}")
                return Response({
                    'code': 500,
                    'message': f'图片处理失败: {str(e)}'
                })

        except Exception as e:
            logger.error(f"处理POST请求时出错: {str(e)}")
            return Response({
                'code': 500,
                'message': f'服务器内部错误: {str(e)}'
            })


# 导入豆包工具
from posters.doubaoTool import generate_image

class DoubaoPostersView(APIView):
    permission_classes = [AllowAny]
    
    def post(self, request):
        try:
            # 获取请求参数
            img = request.data.get('img')  # 原始图片的网络地址
            prompt = request.data.get('prompt')  # 修改提示词

            # 参数验证
            if not img:
                logger.error("缺少原始图片URL")
                return Response({
                    'code': 400,
                    'message': '原始图片URL不能为空'
                })
            
            if not prompt:
                logger.error("缺少修改提示词")
                return Response({
                    'code': 400,
                    'message': '修改提示词不能为空'
                })

            # 调用豆包图片生成API
            try:
                image_url = generate_image(prompt=prompt, image_url=img)
                
                # 确定海报类型
                poster_type = 'modify'  # 使用豆包API修改的海报类型
                
                # 保存记录到数据库（如果用户已登录）
                if hasattr(request, 'user') and request.user.is_authenticated:
                    try:
                        PosterRecord.objects.create(
                            user=request.user,
                            image_url=image_url,
                            prompt=prompt or '',
                            poster_type=poster_type
                        )
                        logger.info(f"用户 {request.user.username} 使用豆包API的海报记录已保存")
                    except Exception as save_error:
                        logger.warning(f"保存豆包API海报记录失败: {str(save_error)}")

                # 返回结果
                return Response({
                    'code': 200,
                    'message': '处理成功',
                    'data': {
                        'image_url': image_url
                    }
                })
            except Exception as e:
                logger.error(f"调用豆包图片生成API失败: {str(e)}")
                return Response({
                    'code': 500,
                    'message': f'图片处理失败: {str(e)}'
                })
        except Exception as e:
            logger.error(f"处理豆包海报POST请求时出错: {str(e)}")
            return Response({
                'code': 500,
                'message': f'服务器内部错误: {str(e)}'
            })

# 海报历史记录接口
class PosterRecordsView(APIView):
    """
    海报记录管理API
    """
    permission_classes = [IsAuthenticated]
    
    def get(self, request):
        """
        获取用户的海报记录列表
        """
        try:
            # 获取查询参数
            poster_type = request.GET.get('poster_type')  # 类型过滤
            search = request.GET.get('search')  # 搜索关键词
            
            # 查询用户的记录（未删除）
            queryset = PosterRecord.objects.filter(
                user=request.user,
                is_deleted=False
            )
            
            # 类型过滤
            if poster_type:
                queryset = queryset.filter(poster_type=poster_type)
            
            # 搜索过滤（在提示词中搜索）
            if search:
                queryset = queryset.filter(
                    Q(prompt__icontains=search) | Q(remark__icontains=search)
                )
            
            # 获取所有记录（按创建时间倒序）
            records = []
            for record in queryset.order_by('-create_time'):
                records.append({
                    'id': record.id,
                    'image_url': record.image_url,
                    'prompt': record.prompt,
                    'poster_type': record.poster_type,
                    'poster_type_display': record.get_poster_type_display(),
                    'create_time': record.create_time.strftime('%Y-%m-%d %H:%M:%S'),
                    'remark': record.remark
                })
            
            return Response({
                'code': 200,
                'message': '获取成功',
                'data': {
                    'records': records,
                    'total_count': len(records)
                }
            })
            
        except Exception as e:
            logger.error(f"获取海报记录失败: {str(e)}")
            return Response({
                'code': 500,
                'message': f'获取记录失败: {str(e)}'
            })
    
    def delete(self, request):
        """
        删除海报记录
        """
        try:
            record_id = request.data.get('id')
            if not record_id:
                return Response({
                    'code': 400,
                    'message': '记录ID不能为空'
                })
            
            # 查找用户的记录
            try:
                record = PosterRecord.objects.get(
                    id=record_id,
                    user=request.user,
                    is_deleted=False
                )
                # 直接删除
                record.delete()
                
                return Response({
                    'code': 200,
                    'message': '删除成功'
                })
            except PosterRecord.DoesNotExist:
                return Response({
                    'code': 404,
                    'message': '记录不存在'
                })
                
        except Exception as e:
            logger.error(f"删除海报记录失败: {str(e)}")
            return Response({
                'code': 500,
                'message': f'删除失败: {str(e)}'
            })


from rest_framework.permissions import AllowAny

# 海报提示词生成的多轮对话接口
class PostersChatView(APIView):
    permission_classes = [IsAuthenticated]
    renderer_classes = [JSONRenderer]  # 使用JSON渲染器支持普通响应和流式响应
    
    def options(self, request, *args, **kwargs):
        """
        处理CORS预检请求，不需要认证
        """
        from rest_framework.response import Response
        response = Response(status=200)
        response['Access-Control-Allow-Origin'] = '*'
        response['Access-Control-Allow-Methods'] = 'GET, POST, PUT, PATCH, DELETE, OPTIONS'
        response['Access-Control-Allow-Headers'] = 'Content-Type, Authorization, Accept, Accept-Encoding, Origin, User-Agent, X-CSRFToken, X-Requested-With'
        response['Access-Control-Allow-Credentials'] = 'true'
        response['Access-Control-Max-Age'] = '3600'
        return response
    
    def get_permissions(self):
        """
        根据请求方法返回不同的权限要求
        """
        if self.request.method == 'OPTIONS':
            return [AllowAny()]
        return super().get_permissions()
    def post(self, request):
        try:
            user_input = request.data.get('message')
            session_id = request.data.get('session_id')  # 会话ID，可选
            stream = request.data.get('stream', True)  # 默认使用流式输出
            
            if not user_input:
                return Response({
                    'code': 400,
                    'message': '消息内容不能为空'
                })

            # 获取或创建会话
            if session_id:
                try:
                    session = ChatSession.objects.get(
                        id=session_id, 
                        user=request.user,
                        is_active=True
                    )
                except ChatSession.DoesNotExist:
                    return Response({
                        'code': 404,
                        'message': '会话不存在'
                    })
            else:
                # 创建新会话，使用用户第一条消息的前10个字符作为标题
                session_title = user_input[:10] + '...' if len(user_input) > 10 else user_input
                session = ChatSession.objects.create(
                    user=request.user,
                    title=session_title
                )

            # 保存用户消息到数据库
            user_message_record = ChatMessage.objects.create(
                session=session,
                message_type='user',
                content=user_input
            )

            # 获取会话的历史消息（不包括刚创建的用户消息）
            history_messages = ChatMessage.objects.filter(
                session=session
            ).exclude(id=user_message_record.id).order_by('create_time')

            # 构建coze的聊天的对话历史
            conversation_history = build_conversation_history_from_db(history_messages)

            # 创建机器人实例并设置历史记录
            user_id = str(request.user.id)
            bot = CozeChatBot(user_id=user_id, conversation_history=conversation_history)

            # 使用流式输出
            def generate_response():
                try:
                    bot_response = ""
                    # 发送初始响应数据，包含会话标题
                    yield f"data: {json.dumps({'session_id': str(session.id), 'title': session.title, 'type': 'start'})}\n\n"
                    
                    # 流式对话
                    for chunk in bot.chat_stream(user_input):
                        if chunk and not chunk.startswith('错误'):
                            bot_response += chunk
                            # 发送增量数据
                            yield f"data: {json.dumps({'type': 'chunk', 'content': chunk})}\n\n"
                    
                    # 保存机器人回复到数据库
                    if bot_response:
                        ChatMessage.objects.create(
                            session=session,
                            message_type='assistant',
                            content=bot_response
                        )
                        # 更新会话的更新时间
                        session.save()
                    
                    # 发送完成信号
                    yield f"data: {json.dumps({'type': 'end', 'message_id': user_message_record.id})}\n\n"
                    
                except Exception as e:
                    logger.error(f"流式对话失败: {str(e)}")
                    yield f"data: {json.dumps({'type': 'error', 'message': str(e)})}\n\n"

            # 返回流式响应
            def streaming_generator():
                for data in generate_response():
                    yield data
            
            response = StreamingHttpResponse(
                streaming_generator(),
                content_type='text/plain; charset=utf-8'
            )
            # 设置完整的CORS响应头
            response['Cache-Control'] = 'no-cache'
            response['Access-Control-Allow-Origin'] = '*'
            response['Access-Control-Allow-Headers'] = 'Content-Type, Authorization, Accept, Accept-Encoding, Origin, User-Agent, X-CSRFToken, X-Requested-With'
            response['Access-Control-Allow-Methods'] = 'GET, POST, PUT, PATCH, DELETE, OPTIONS'
            response['Access-Control-Expose-Headers'] = 'Content-Type, Cache-Control'
            response['Access-Control-Allow-Credentials'] = 'true'
            response['X-Accel-Buffering'] = 'no'  # 禁用nginx缓冲
            
            logger.info(f"返回流式响应，Content-Type: {response['Content-Type']}")
            return response

        except Exception as e:
            logger.error(f"聊天处理失败: {str(e)}")
            return Response({
                'code': 500,
                'message': f'聊天处理失败: {str(e)}'
            })

    def get(self, request):
        """
        获取用户的聊天会话列表
        """
        try:
            # 获取用户的所有活跃会话
            sessions = ChatSession.objects.filter(
                user=request.user,
                is_active=True
            ).order_by('-update_time')

            session_list = []
            for session in sessions:
                # 获取最后一条消息作为预览
                last_message = ChatMessage.objects.filter(
                    session=session
                ).order_by('-create_time').first()

                session_list.append({
                    'session_id': str(session.id),
                    'title': session.title,
                    'last_message': last_message.content[:50] + '...' if last_message and len(last_message.content) > 50 else (last_message.content if last_message else ''),
                    'last_message_time': last_message.create_time.strftime('%Y-%m-%d %H:%M:%S') if last_message else session.create_time.strftime('%Y-%m-%d %H:%M:%S'),
                    'create_time': session.create_time.strftime('%Y-%m-%d %H:%M:%S'),
                    'message_count': ChatMessage.objects.filter(session=session).count()
                })

            return Response({
                'code': 200,
                'message': '获取成功',
                'data': {
                    'sessions': session_list
                }
            })

        except Exception as e:
            logger.error(f"获取会话列表失败: {str(e)}")
            return Response({
                'code': 500,
                'message': f'获取会话列表失败: {str(e)}'
            })



# 海报提示词聊天助手的历史会话管理
class ChatSessionDetailView(APIView):
    """
    聊天会话详情管理
    """
    permission_classes = [IsAuthenticated]

    def get(self, request, session_id):
        """
        获取指定会话的消息历史
        """
        try:
            # 验证会话是否存在且属于当前用户
            try:
                session = ChatSession.objects.get(
                    id=session_id,
                    user=request.user,
                    is_active=True
                )
            except ChatSession.DoesNotExist:
                return Response({
                    'code': 404,
                    'message': '会话不存在'
                })

            # 获取会话的所有消息
            messages = ChatMessage.objects.filter(
                session=session
            ).order_by('create_time')

            message_list = []
            for message in messages:
                message_list.append({
                    'id': message.id,
                    'message_type': message.message_type,
                    'content': message.content,
                    'create_time': message.create_time.strftime('%Y-%m-%d %H:%M:%S')
                })

            return Response({
                'code': 200,
                'message': '获取成功',
                'data': {
                    'session_id': str(session.id),
                    'title': session.title,
                    'messages': message_list,
                    'create_time': session.create_time.strftime('%Y-%m-%d %H:%M:%S')
                }
            })

        except Exception as e:
            logger.error(f"获取会话详情失败: {str(e)}")
            return Response({
                'code': 500,
                'message': f'获取会话详情失败: {str(e)}'
            })

    def delete(self, request, session_id):
        """
        删除指定会话（直接删除）
        """
        try:
            try:
                session = ChatSession.objects.get(
                    id=session_id,
                    user=request.user,
                    is_active=True
                )
                # 根据项目规范，使用直接删除而非软删除
                session.delete()

                return Response({
                    'code': 200,
                    'message': '删除成功'
                })
            except ChatSession.DoesNotExist:
                return Response({
                    'code': 404,
                    'message': '会话不存在'
                })

        except Exception as e:
            logger.error(f"删除会话失败: {str(e)}")
            return Response({
                'code': 500,
                'message': f'删除会话失败: {str(e)}'
            })


